﻿using System;
using Firefly.Framework.Collections;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace Firefly.Framework.Components
{
    public abstract class UpdateableComponent : IUpdateableComponent
    {
        public UpdateableComponent()
            : this(null)
        {
        }

        public UpdateableComponent(Game game)
        {
            Game = game;
            Enabled = true;
            UpdateOrder = 0;
            Children = new ComponentCollection();
        }

        #region IComponent Members

        [ContentSerializer(Optional = true)]
        public virtual IComponent Parent { get; set; }
        [ContentSerializer(Optional = true)]
        public ComponentCollection Children { get; protected set; }

        #endregion

        #region IUpdateableComponent Members

        [ContentSerializerIgnore]
        public Game Game { get; protected set; }

        #endregion

        #region IUpdateable Members

        public event EventHandler EnabledChanged;
        public event EventHandler UpdateOrderChanged;

        private bool _enabled;
        private int _updateOrder;
        
        [ContentSerializer(Optional = true)]
        public bool Enabled
        {
            get { return _enabled; }
            set
            {
                if (value != _enabled)
                {
                    _enabled = value;
                    NotifyEnabledChanged();
                }
            }
        }
        [ContentSerializer(Optional = true)]
        public int UpdateOrder
        {
            get { return _updateOrder; }
            set
            {
                if (value != _updateOrder)
                {
                    _updateOrder = value;
                    NotifyUpdateOrderChanged();
                }
            }
        }

        protected void NotifyEnabledChanged()
        {
            EventHandler handler = EnabledChanged;

            if (handler != null)
            {
                handler(this, new EventArgs());
            }
        }

        protected void NotifyUpdateOrderChanged()
        {
            EventHandler handler = UpdateOrderChanged;

            if (handler != null)
            {
                handler(this, new EventArgs());
            }
        }

        public virtual void Update(GameTime gameTime)
        {
            if (Enabled)
            {
                Children.Update(gameTime);
            }
        }

        #endregion

        #region IGameComponentEx Members

        [ContentSerializerIgnore]
        public bool Initialized { get; protected set; }

        public void Uninitialize()
        {
        }

        #endregion

        #region IGameComponent Members

        public void Initialize()
        {
            Initialized = true;
        }

        #endregion

        #region IDisposableEx Members

        [ContentSerializerIgnore]
        public bool Disposed { get; protected set; }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected abstract void Dispose(bool disposing);

        #endregion
    }
}
